/***** BEGIN LICENSE BLOCK *****
Copyright the original author Andy Shaules ( bowljoman AT hotmail DOT com) thebitstream.com
Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
	http://www.mozilla.org/MPL/MPL-1.1.html
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

# ***** END LICENSE BLOCK *****/
package sandy.redSandy
{
	import flash.net.NetConnection;
	import flash.net.Responder;
	import flash.events.IEventDispatcher;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.NetStatusEvent;
	import flash.events.AsyncErrorEvent;
	/**
	 * 
	 * @author Andy Shaules
	 * 
	 */	
	internal class RedSandyConnector extends NetConnection
	{
		
		public var clientData:Object;
		private var _dispatcher:Connection=new Connection();
		private var _sandyClient:IRedSandy;
		
		public function set sandyClient(val:IRedSandy):void
		{
			_sandyClient=val;
		}
		public function set dispatcher(obj:Connection):void
		{
			super.removeEventListener(NetStatusEvent.NET_STATUS,_dispatcher.dispatchEvent);
			super.removeEventListener(AsyncErrorEvent.ASYNC_ERROR,_dispatcher.dispatchEvent);
			_dispatcher=null;
			_dispatcher=obj;
			super.addEventListener(NetStatusEvent.NET_STATUS,_dispatcher.dispatchEvent);
			super.addEventListener(AsyncErrorEvent.ASYNC_ERROR,_dispatcher.dispatchEvent);
		}
		public function RedSandyConnector()
		{
			super();
			super.client=this;
			super.addEventListener(NetStatusEvent.NET_STATUS,_dispatcher.dispatchEvent);
			super.addEventListener(AsyncErrorEvent.ASYNC_ERROR,_dispatcher.dispatchEvent);
		}
		public function getAllProperties(callBack:Function=null):void
		{
				call('property.getAll',new Responder(onResult2));
				function onResult2(obj2:Object):void
				{
	
					clientData=obj2[0];
					if(callBack!=null)
					callBack.call(this,obj2[0]);
				}			
		}
		public function getProperty(key:String,callBack:Function):void
		{
			call('property.getProperty',new Responder(onResult),key);
			function onResult(obj:Object):void
			{
					if(!clientData)
					{
						clientData=new Object()
					}
					clientData[key]=obj;
					
					if(callBack!=null)
					callBack.call(this,obj);				
				
			}			
		}
		public function setProperty(key:String,value:Object,callBack:Function=null):void
		{
			call('property.setProperty',new Responder(onResult),key,value);
			function onResult(obj:Object):void
			{
					if(callBack!=null)
					callBack.call(this,obj);					
			}			
		}
		public function getUserProperty(user:String,key:String,callBack:Function):void
		{
			call('property.getUserProperty',new Responder(onResult),user,key);
			function onResult(obj:Object):void
			{
					if(callBack!=null)
					callBack.call(this,obj);				
			}			
		}		
		public function sendEvent(data:Object):void
		{
			call('event.sendEvent',new Responder(null),data);		
		}
		public function onEvent(obj:Object):void
		{
			obj[1][0].senderId=obj[0];
			_sandyClient.onEvent(obj[1][0]);
		}
		public function onLeave(obj:Object):void
		{
			_sandyClient.onLeave(obj);
		}		
		public function onJoin(obj:Object):void
		{
			var stfg:SharedTransformGroup=new SharedTransformGroup(obj.id);
			_sandyClient.onJoined(obj,stfg);
		}
		/**
		 * The server calls this function periodically with positional properties.
		 * Find your session id in the stream header, and match it to your data packet.
		 * Return your new positional data.
		 * @param obj
		 * @return The return is distributed to all clients in the next stream segment. 
		 * 
		 */	
		public function onSandy(obj:Object):Object
		{
			// STREAM PACKET LAYOUT
			//
			
			// obj[0] stream header. Personal client data.
			//  	obj[0][0] personal server assigned unique session id.
			//		obj[0][1] personal client properties.
			//		obj[0][2] A unix timestamp in seconds.		
			
			// obj[1] stream packet for player 1.
			//		obj[1][0][0] session id of player 1 packet info.
			//		obj[1][0][1] x
			//		obj[1][0][2] y
			//		obj[1][0][3] z
			//		obj[1][0][4] rX		
			//		obj[1][0][5] rY
			//		obj[1][0][6] rZ ...etc
			
			// obj[2] stream packet for player 2.		 
			//		obj[2][0][0] session id of player 2 packet info.			
			//		...etc
			
			// obj[3] stream packet for player 3.		 
			//		...etc	
			
			// obj[4] stream packet for player 4.		 
			//		...etc
			
			
			// Does my group exist yet?
			if(SharedTransformGroup.getSharedTransformGroup(obj[0][0])==null)
			{	
				//make one for me			
				var stfg:SharedTransformGroup=new SharedTransformGroup(obj[0][0]);
				_sandyClient.onCreated(stfg);
			}
			// Get my client properties from the header.
			clientData=obj[0][1];

			// Do we have a handler?
			if(_sandyClient)
			{
				var position:SharedTransformGroup;
				for (var j:int=1; j<obj.length;j++)
				{
				//Match packet id with my id.
					if(obj[j][0]==obj[0][0])
					{	
						// here is my positional data.
						SharedTransformGroup.getSharedTransformGroup(obj[j][0]).when=new Date().time; 
						_sandyClient.onInput(SharedTransformGroup.getSharedTransformGroup(obj[j][0]) ) ;			
						position=SharedTransformGroup.getSharedTransformGroup(obj[j][0])
					}else //other user's
					{
							if(SharedTransformGroup.getSharedTransformGroup(obj[j][0])!=null)
							SharedTransformGroup.getSharedTransformGroup(obj[j][0]).onRedSandyPacket(obj[j]);	
					}
				
				}				
				if(position)
				{
					//return my position object.
					// Next stream segment will distribute values.
					
					
					
					return position.toObject();
				}
			
			}
			
			//else we find and return defaults
					
			var ret:Object;
			for (var i:int=1; i<obj.length;i++)
			{
				if(obj[i][0]==obj[0][0])
				{	
					ret=obj[i][1];					
				}else
				{
					if(SharedTransformGroup.getSharedTransformGroup(obj[i][0])!=null)
					SharedTransformGroup.getSharedTransformGroup(obj[i][0]).onRedSandyPacket(obj[i]);
				
				}
			}
			
			return (ret);
		}
	}
}